package com.mhy.mlkit

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.graphics.Rect
import android.graphics.RectF
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.util.Size
import android.view.ViewTreeObserver
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.camera.core.*
import androidx.camera.lifecycle.ProcessCameraProvider
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.LifecycleOwner
import com.google.common.util.concurrent.ListenableFuture
import kotlinx.android.synthetic.main.layout_scanning.*
import java.nio.charset.Charset
import java.util.concurrent.Executors


class ScanningActivity : AppCompatActivity() {

    private  val TAG = "ScanningActivity"

    private lateinit var cameraProviderFuture : ListenableFuture<ProcessCameraProvider>

    private var listener : OverlayListener? = null

    private var camera : Camera? = null

    private var scaleX = 0f

    private var scaleY = 0f

    companion object{
        const val SCAN_RESULT = "result"
        const val REQUEST_PERMISSION = 12345
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.layout_scanning)
        //当FitsSystemWindows设置 true 时，会在屏幕最上方预留出状态栏高度的 padding
        // 想要图片沉浸, 必须设置fitsSystemWindows=false
        Utils.setRootViewFitsSystemWindows(this, false)
        //设置状态栏透明
        Utils.setTranslucentStatus(this)
        //所以如果你是这种情况,请使用以下代码, 设置状态使用深色文字图标风格, 否则你可以选择性注释掉这个if内容
        if (!Utils.setStatusBarDarkTheme(this, false)) {
            //如果不支持设置深色风格 为了兼容总不能让状态栏白白的看不清, 于是设置一个状态栏颜色为半透明,
            //这样半透明+白=灰, 状态栏的文字能看得清
            Utils.setStatusBarColor(this, 0x55000000)
        }
        ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE),
            REQUEST_PERMISSION
        )
        cameraProviderFuture = ProcessCameraProvider.getInstance(this)
        listener = OverlayListener()
        overlay.viewTreeObserver.addOnGlobalLayoutListener(listener)
        window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
    }

    override fun onDestroy() {
        super.onDestroy()
        window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
    }
    inner class OverlayListener : ViewTreeObserver.OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            cameraProviderFuture.addListener(Runnable {
                val cameraProvider = cameraProviderFuture.get()
                bindScan(cameraProvider, overlay.width, overlay.height)
            }, ContextCompat.getMainExecutor(this@ScanningActivity))
            overlay.viewTreeObserver.removeOnGlobalLayoutListener(listener)
        }
    }

    @SuppressLint("UnsafeExperimentalUsageError")
    private fun bindScan(cameraProvider: ProcessCameraProvider,width : Int, height : Int){
        Log.i(TAG, "bindScan: width:$width height:$height")
        val preview : Preview = Preview.Builder()
            .build()
        //绑定预览
        preview.setSurfaceProvider(previewView.surfaceProvider)
        //使用后置相机
        val cameraSelector : CameraSelector = CameraSelector.Builder()
            .requireLensFacing(CameraSelector.LENS_FACING_BACK)
            .build()
        //配置图片扫描
        val imageAnalysis = ImageAnalysis.Builder()
            .setTargetResolution(Size(width, height))
            .setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
            .build()
        //绑定图片扫描解析
        imageAnalysis.setAnalyzer(Executors.newSingleThreadExecutor(),
            QRCodeAnalyser { barcode, imageWidth, imageHeight ->
                //解绑当前所有相机操作
                cameraProvider.unbindAll()
                //初始化缩放比例
                initScale(imageWidth, imageHeight)
                barcode.boundingBox?.let {//扫描二维码的外边框矩形
                    overlay.addRect(translateRect(it))
                    Log.i(TAG, "bindScan: left:${it.left} right:${it.right} top:${it.top} bottom:${it.bottom}")
                }
                Handler(Looper.getMainLooper()).post {
                    val intent = Intent()
                   val betys= barcode.rawBytes?: byteArrayOf("scan err".toByte())//emptyArray<Byte>()//
                    //判断二维码图是gbk编码还是utf-8编码
                   val charset= Utils.guessEncoding(betys)//"GBK"  UTF8
                   val display= String(betys,Charset.forName(charset))
                    Log.e("QRresult: "+charset,display)
                    intent.putExtra(SCAN_RESULT, display)//barcode.rawValue
                    setResult(Activity.RESULT_OK, intent)
                    finish()
                }
            })
        //将相机绑定到当前控件的生命周期
        camera = cameraProvider.bindToLifecycle(this as LifecycleOwner, cameraSelector, imageAnalysis, preview)
    }

    private fun translateX(x: Float): Float = x * scaleX
    private fun translateY(y: Float): Float = y * scaleY

    //将扫描的矩形换算为当前屏幕大小
    private fun translateRect(rect: Rect) = RectF(
        translateX(rect.left.toFloat()),
        translateY(rect.top.toFloat()),
        translateX(rect.right.toFloat()),
        translateY(rect.bottom.toFloat())
    )

    private fun initScale(imageWidth : Int, imageHeight : Int){
        if(isPortraitMode()){
            scaleY = overlay.height.toFloat() / imageWidth.toFloat()
            scaleX = overlay.width.toFloat() / imageHeight.toFloat()
        }else{
            scaleY = overlay.height.toFloat() / imageHeight.toFloat()
            scaleX = overlay.width.toFloat() / imageWidth.toFloat()
        }
    }
}